#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
// #define SelfDefine 1
namespace protecol_ns // 协议
{
    const std::string ProtSep = " ";
    const std::string SEP = "\r\n";
    // 解决tcp粘报问题
    std::string add_header(const std::string &json_str) // 给json字符串添加长度，及标志位，判断报文是否完整
    {
        int json_str_len = json_str.size();
        std::string header_str = std::to_string(json_str_len); // 将长度转为字符串
        header_str += SEP;
        header_str += json_str;
        header_str += SEP;
        return header_str;
    }
    // "len"\r\n"{
    // "len"\r\n"{             }"
    // "len"\r\n"{             }"\r\n;
    // "len"\r\n"{             }"\r\n"len";
    // "len"\r\n"{             }"\r\n"len"\r\n"{             }";
    // "len"\r\n"{             }"\r\n"len"\r\n"{             }"\r\n
    std::string dele_header(std::string &inbuffer) // 取出报文中的有效信息
    {
        auto pos = inbuffer.find(SEP);
        if (pos == std::string::npos)
            return std::string();
        std::string len_str = inbuffer.substr(0, pos); // 截取0 到pos 位置字符串，取出报文长度信息字符串
        if (len_str.empty())
            return std::string();
        int packlen = std::stoi(len_str);

        int total = packlen + len_str.size() + SEP.size() * 2;
        if (inbuffer.size() < total)
        {
            return std::string();
        }
        std::string package = inbuffer.substr(pos + SEP.size(), packlen);
        inbuffer.erase(0, total);
        return package;
    }
    class request
    {
    public:
        request()
        {
        }
        request(int x, int y, int oper)
            : _x(x), _y(y), _oper(oper)
        {
        }
        bool serialize(std::string *out) // 信息序列化，参数为指向字符串的指针
        {
#ifdef SelfDefine
            *out = std::to_string(_x) + ProtSep + _oper + ProtSep + std::to_string(_y);
            return true;
#else
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["oper"] = _oper;
            Json::FastWriter writer;   // 创建了一个 Json::FastWriter 类的实例 writer，这个类负责将 Json::Value 对象转换成字符串。
            *out = writer.write(root); // 将root JSON对象转换为字符串
            return true;
#endif
        }
        bool deserializtion(const std::string &in) // 信息反序列化 将字符串变为结构化数据
        {
#ifdef SelfDefine
            auto left = in.find(ProtSep);
            if (left == std::string::npos)
            {
                return false;
            }
            auto right = in.rfind(ProtSep); // 从右边开始寻找空格
            if (right == std::string::npos)
            {
                return false;
            }
            _x = std::stoi(in.substr(0, left));                                              // 截取x
            _y = std::stoi(in.substr(right + ProtSep.size()));                               // 截取y
            std::string oper = in.substr(left + ProtSep.size(), right - (left + ProtSep.size())); // 截取操作符
            if (oper.size() != 1)
            {
                return false;
            }
            _oper = oper[0];
            return true;

#else
            Json::Value root;
            Json::Reader reader;
            bool res = reader.parse(in, root);
            if (!res)
            {
                return false;
            }
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();
            return true;
#endif
        }

    public:
        int _x;
        int _y;
        char _oper; // 操作 加减乘除
    };
    class response
    {
    public:
        response()
        {
        }
        response(int result, int code) // 结果序列化
            : _result(result), _code(code)
        {
        }
        bool serialize(std::string *out)
        {
#ifdef SelfDefine
            *out = std::to_string(_result) + ProtSep + std::to_string(_code);
            return true;
#else
            Json::Value root;
            root["result"] = _result;
            root["code"] = _code;
            Json::FastWriter writer;
            *out = writer.write(root); // 将Json 对象 root 序列化
            return true;
#endif
        }
        bool deserializtion(const std::string &in) // 结果反序化 "_result _code" [)
        {
#ifdef SelfDefine
            auto pos = in.find(ProtSep); // 寻早空格下标
            if (pos == std::string::npos)
            {
                return false;
            }
            _result = std::stoi(in.substr(0, pos));             // 获取结果
            _code = std::stoi(in.substr(pos + ProtSep.size())); // 获取退出码
            return true;
#else
            Json::Value root;
            Json::Reader reader;               // Json::Reader 类负责将Json字符串解析为Json::Value对象
            bool res = reader.parse(in, root); // 将Json字符串解析为Json::Value对象root
            if (!res)
                return false;
            _result = root["result"].asInt();
            _code = root["code"].asInt();
            return true;
#endif
        }
        ~response()
        {
        }

    public:
        int _result; // 结果
        int _code;   // 退出码
    };
    class factory
    {
    public:
        factory()
        {
            _opers = "+-*/%";
            srand(time(nullptr) ^ getpid());
        }
        std::shared_ptr<request> build_request() // 创建请求
        {
            int x = rand() % 10 + 1; // 1~10
            usleep(x * 10);
            int y = rand() % 5 + 1; // 1~5
            usleep(x * y * 10);
            char oper = _opers[rand() % _opers.size()];
            std::shared_ptr<request> req = std::make_shared<request>(x, y, oper);
            return req;
        }
        std::shared_ptr<response> build_response() // 创建应答
        {
            return std::make_shared<response>();
        }
        ~factory()
        {
        }

    private:
        std::string _opers;
    };
}